package com.atguigu.crowd.mvc.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//@Configuration表示当前类是配置类

@Configuration
@EnableWebSecurity
//使用全局方法设置，并设置prePostEnabled生效
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebAppSercurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
   UserDetailsService userDetailsService;

    @Autowired
    BCryptPasswordEncoder passwordEncoder;
    @Bean
    public BCryptPasswordEncoder getPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(HttpSecurity security) throws Exception {
        // 与 SpringSecurity 环境下请求授权相关
      security.authorizeRequests()
              .antMatchers("/index.jsp")
              .permitAll()                                       //给请求授权
              .antMatchers("/admin/login/page.html")          //放行登录页面
              .permitAll()                                               //无条件访问
              .antMatchers("/bootstrap/**")                  //针对静态资源进行设置
              .permitAll()
              .antMatchers("/crowd/**")
              .permitAll()
              .antMatchers("/css/**")
              .permitAll()
              .antMatchers("/fonts/**")
              .permitAll()
              .antMatchers("/img/**")
              .permitAll()
              .antMatchers("/jquery/**")
              .permitAll()
              .antMatchers("/layer/**")
              .permitAll()
              .antMatchers("/script/**")
              .permitAll()
              .antMatchers("/WEB-INF/**")
              .permitAll()
              .antMatchers("/ztree/**")
              .permitAll()

              .antMatchers("/admin/get/page.html")
//              .hasRole("经理")
              .access("hasRole('经理') or hasAuthority('user:get')") // 必须具有经理的角色
              .anyRequest()
              .authenticated()

              .and()
              .exceptionHandling()
              .accessDeniedHandler(new AccessDeniedHandler() {
                  @Override
                  public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                      httpServletRequest.setAttribute("exception",new Exception("抱歉，您没有权限访问该资源！"));
                      httpServletRequest.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(httpServletRequest,httpServletResponse);
                  }
              })
              .and()
              .csrf()
              .disable()                                                //禁止防止跨站伪造
              .formLogin()                                                     //开启登录的功能
              .loginPage("/admin/login/page.html")                               //指定登录界面
              .loginProcessingUrl("/security/do/login.html")                   //指定处理登录请求的地址
              .defaultSuccessUrl("/admin/main/page.html")                     // 登录成功之后的地址
              .permitAll()
              .usernameParameter("LoginAcct")
              .passwordParameter("userPswd").and()
              .logout()                  //退出的地址
              .logoutUrl("/security/do/logout.html")                            //退出的地址
              .logoutSuccessUrl("/admin/login/page.html");              //退出成功之后的地址


    }

    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
//    builder.inMemoryAuthentication().withUser("zhangsan").password("123").roles("admin");
        // 使用userDetailsService，即配置的数据库验证登录
        builder.userDetailsService(userDetailsService)
//        使用BCryptPasswordEncoder进行带盐值的密码加密
        .passwordEncoder(passwordEncoder);
    }
}
